简介
node 读取文件目录实现去中心化管理路由
背景
最近写node项目发现路由太多,手动require不符合程序员的气质。为了偷懒只能写一段代码自动导入了。
目录结构
│─app.js // 入口文件
│─router // 路由文件夹
│ │─router.js // 路由集中
│ ├─V1 //版本文件
│ │ └─test.js // 路由
│ └─V2
│ └─test.js
│─utils
└─requireContext.js // 工具函数
app.js
// app.js 代码
const Koa = require('koa')
const routes = require('./router/router.js')
const app = new Koa()
// 挂载路由
app.use(routes)
app.listen(3000)
router.js
// router/router.js 作为路由的集中地
const path = require('path')
const compose = require('koa-compose')
const requireContext = require('../utils/requireContext.js')
// 原来的写法
/*
const routes = compose([
//需要将所有的路由导入进来
require('./V1/test.js').routes(),
require('./V1/test.js').routes(),
])
*/
//现在的写法 新曾路由文件再也不用手动导入了
// 参数1 文件路径
// 参数2 正则 这里是 不是router.js结尾的所有js
// 参数3 递归子目录
let files = requireContext(path.resolve(__dirname, './'), /(?<!router)\.js$/, true)
console.log(files);
const routes = compose(files.map(item => require(item).routes()))
// 导出路由中间件集合
module.exports = routes
test.js
// router/V1/test.js router/V2/test.js
const Router = require('koa-router')
const router = new Router()
router.prefix('/V2')
router.get('/test', (ctx, next) => {
ctx.body = 'hello'
})
// 导出路由
module.exports = router
requireContext.js
// 文件加载去中心化
const fs = require('fs')
const path = require('path')
/**
* @param {String} filePath 目录绝对路径
* @param {Regexp} filters 过滤器
* @param {Boolean} deep 是否遍历子目录
* @returns {Array}
*/
function requireContext(filePath, filters, deep) {
// 文件直接退出
if (fs.statSync(filePath).isFile()) {
return [filePath]
}
// 过滤器不是正则
if (filters && !(filters instanceof RegExp)) {
throw new Error('filters must Regexp')
}
let filesArray = []
findFile(filePath, deep, filesArray)
return filters ? filesArray.filter(item => filters.test(item)) : filesArray
}
function findFile(filePath, deep, filesArray) {
let files = fs.readdirSync(filePath)
files.forEach(item => {
let fPath = path.resolve(filePath, item)
if (fs.statSync(fPath).isFile()) {
filesArray.push(fPath)
} else if (deep) {
findFile(fPath, deep, filesArray)
}
})
}
module.exports = requireContext
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。